<!DOCTYPE html>
<html lang="zh-CN" data-theme="light">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <meta name="generator" content="VuePress 2.0.0-beta.38" />
    <meta name="theme" content="VuePress Theme Hope" />
    <meta property="og:url" content="https://javaguide.cn/system-design/framework/mybatis/mybatis-interview.html"><meta property="og:site_name" content="JavaGuide"><meta property="og:title" content="MyBatis 常见面试总结"><meta property="og:type" content="article"><meta property="og:updated_time" content="2021-11-09T10:47:58.000Z"><meta property="og:locale" content="zh-CN"><meta property="article:modified_time" content="2021-11-09T10:47:58.000Z"><script>var _hmt = _hmt || [];
      (function() {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?5dd2e8c97962d57b7b8fea1737c01743";
        var s = document.getElementsByTagName("script")[0]; 
        s.parentNode.insertBefore(hm, s);
      })();</script><link rel="stylesheet" href="//at.alicdn.com/t/font_2922463_99aa80ii7cf.css"><title>MyBatis 常见面试总结 | JavaGuide</title><meta name="description" content="Java学习&&面试指南">
    <style>
      :root {
        --bg-color: #fff;
      }

      html[data-theme="dark"] {
        --bg-color: #1d2025;
      }

      html,
      body {
        background-color: var(--bg-color);
      }
    </style>
    <script>
      const userMode = localStorage.getItem("vuepress-theme-hope-scheme");
      const systemDarkMode =
        window.matchMedia &&
        window.matchMedia("(prefers-color-scheme: dark)").matches;

      if (userMode === "dark" || (userMode !== "light" && systemDarkMode)) {
        document.querySelector("html").setAttribute("data-theme", "dark");
      }
    </script>
    <link rel="stylesheet" href="/assets/style.aa943f56.css">
    <link rel="modulepreload" href="/assets/app.93341f6d.js"><link rel="modulepreload" href="/assets/mybatis-interview.html.ac1463ae.js"><link rel="modulepreload" href="/assets/mybatis-interview.html.9a7de2a9.js"><link rel="modulepreload" href="/assets/plugin-vue_export-helper.21dcd24c.js">
  </head>
  <body>
    <div id="app"><!--[--><!--[--><!--[--><span tabindex="-1"></span><a href="#main-content" class="skip-link sr-only">Skip to content</a><!--]--><div class="theme-container has-toc sidebar-open"><!--[--><header class="navbar"><button class="toggle-sidebar-button" title="Toggle Sidebar"><span class="icon"></span></button><a href="/" class="home-link"><img class="logo" src="/logo.png" alt="JavaGuide"><!----><span class="site-name hide-in-pad">JavaGuide</span><!--[--><!----><!--]--></a><nav class="nav-links" style=""><div class="nav-item hide-in-mobile"><a href="/home.html" class="nav-link" arialabel="面试指南"><i class="icon iconfont icon-java"></i>面试指南<!----></a></div><div class="nav-item hide-in-mobile"><a href="/zhuanlan/" class="nav-link" arialabel="优质专栏"><i class="icon iconfont icon-recommend"></i>优质专栏<!----></a></div><div class="nav-item hide-in-mobile"><a href="/open-source-project/" class="nav-link" arialabel="项目精选"><i class="icon iconfont icon-github"></i>项目精选<!----></a></div><div class="nav-item hide-in-mobile"><a href="/books/" class="nav-link" arialabel="书籍精选"><i class="icon iconfont icon-book"></i>书籍精选<!----></a></div><div class="nav-item hide-in-mobile"><a href="https://snailclimb.gitee.io/javaguide/#/" rel="noopener noreferrer" target="_blank" arialabel="旧版链接" class="nav-link"><i class="icon iconfont icon-java"></i>旧版链接<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!----></a></div><div class="nav-item hide-in-mobile"><a href="https://javaguide.cn/feed.json" rel="noopener noreferrer" target="_blank" arialabel="RSS订阅" class="nav-link"><i class="icon iconfont icon-rss"></i>RSS订阅<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!----></a></div><div class="nav-item hide-in-mobile"><a href="/about-the-author/" class="nav-link" arialabel="关于作者"><i class="icon iconfont icon-zuozhe"></i>关于作者<!----></a></div></nav><div class="nav-actions-wrapper"><!--[--><!----><!--]--><div class="nav-item"><!----></div><div class="nav-item"><a class="repo-link" href="https://github.com/Snailclimb/JavaGuide" target="_blank" rel="noopener noreferrer"><svg xmlns="http://www.w3.org/2000/svg" class="icon github-icon" viewbox="0 0 1024 1024" arialabelledby="github" style="width:1.25rem;height:1.25rem;vertical-align:middle;"><title id="github" lang="en">github icon</title><g fill="currentColor"><path d="M511.957 21.333C241.024 21.333 21.333 240.981 21.333 512c0 216.832 140.544 400.725 335.574 465.664 24.49 4.395 32.256-10.07 32.256-23.083 0-11.69.256-44.245 0-85.205-136.448 29.61-164.736-64.64-164.736-64.64-22.315-56.704-54.4-71.765-54.4-71.765-44.587-30.464 3.285-29.824 3.285-29.824 49.195 3.413 75.179 50.517 75.179 50.517 43.776 75.008 114.816 53.333 142.762 40.79 4.523-31.66 17.152-53.377 31.19-65.537-108.971-12.458-223.488-54.485-223.488-242.602 0-53.547 19.114-97.323 50.517-131.67-5.035-12.33-21.93-62.293 4.779-129.834 0 0 41.258-13.184 134.912 50.346a469.803 469.803 0 0 1 122.88-16.554c41.642.213 83.626 5.632 122.88 16.554 93.653-63.488 134.784-50.346 134.784-50.346 26.752 67.541 9.898 117.504 4.864 129.834 31.402 34.347 50.474 78.123 50.474 131.67 0 188.586-114.73 230.016-224.042 242.09 17.578 15.232 33.578 44.672 33.578 90.454v135.85c0 13.142 7.936 27.606 32.854 22.87C862.25 912.597 1002.667 728.747 1002.667 512c0-271.019-219.648-490.667-490.71-490.667z"></path></g></svg></a></div><div class="nav-item hide-in-mobile"><button id="appearance-switch"><svg xmlns="http://www.w3.org/2000/svg" class="icon auto-icon" viewbox="0 0 1024 1024" arialabelledby="auto" style="display:block;"><title id="auto" lang="en">auto icon</title><g fill="currentColor"><path d="M512 992C246.92 992 32 777.08 32 512S246.92 32 512 32s480 214.92 480 480-214.92 480-480 480zm0-840c-198.78 0-360 161.22-360 360 0 198.84 161.22 360 360 360s360-161.16 360-360c0-198.78-161.22-360-360-360zm0 660V212c165.72 0 300 134.34 300 300 0 165.72-134.28 300-300 300z"></path></g></svg><svg xmlns="http://www.w3.org/2000/svg" class="icon dark-icon" viewbox="0 0 1024 1024" arialabelledby="dark" style="display:none;"><title id="dark" lang="en">dark icon</title><g fill="currentColor"><path d="M524.8 938.667h-4.267a439.893 439.893 0 0 1-313.173-134.4 446.293 446.293 0 0 1-11.093-597.334A432.213 432.213 0 0 1 366.933 90.027a42.667 42.667 0 0 1 45.227 9.386 42.667 42.667 0 0 1 10.24 42.667 358.4 358.4 0 0 0 82.773 375.893 361.387 361.387 0 0 0 376.747 82.774 42.667 42.667 0 0 1 54.187 55.04 433.493 433.493 0 0 1-99.84 154.88 438.613 438.613 0 0 1-311.467 128z"></path></g></svg><svg xmlns="http://www.w3.org/2000/svg" class="icon light-icon" viewbox="0 0 1024 1024" arialabelledby="light" style="display:none;"><title id="light" lang="en">light icon</title><g fill="currentColor"><path d="M952 552h-80a40 40 0 0 1 0-80h80a40 40 0 0 1 0 80zM801.88 280.08a41 41 0 0 1-57.96-57.96l57.96-58a41.04 41.04 0 0 1 58 58l-58 57.96zM512 752a240 240 0 1 1 0-480 240 240 0 0 1 0 480zm0-560a40 40 0 0 1-40-40V72a40 40 0 0 1 80 0v80a40 40 0 0 1-40 40zm-289.88 88.08-58-57.96a41.04 41.04 0 0 1 58-58l57.96 58a41 41 0 0 1-57.96 57.96zM192 512a40 40 0 0 1-40 40H72a40 40 0 0 1 0-80h80a40 40 0 0 1 40 40zm30.12 231.92a41 41 0 0 1 57.96 57.96l-57.96 58a41.04 41.04 0 0 1-58-58l58-57.96zM512 832a40 40 0 0 1 40 40v80a40 40 0 0 1-80 0v-80a40 40 0 0 1 40-40zm289.88-88.08 58 57.96a41.04 41.04 0 0 1-58 58l-57.96-58a41 41 0 0 1 57.96-57.96z"></path></g></svg></button></div><form class="search-box" role="search"><input type="search" placeholder="搜索" autocomplete="off" spellcheck="false" value><!----></form><button class="toggle-navbar-button" aria-label="Toggle Navbar" aria-expanded="false" aria-controls="nav-screen"><span class="button-container"><span class="button-top"></span><span class="button-middle"></span><span class="button-bottom"></span></span></button><!--[--><!----><!--]--></div></header><!----><!--]--><!----><div class="toggle-sidebar-wrapper"><span class="arrow left"></span></div><aside class="sidebar"><!--[--><!----><!--]--><ul class="sidebar-links"><li><!--[--><section class="sidebar-group"><button class="sidebar-heading clickable"><i class="icon iconfont icon-mianshi"></i><span class="title">面试准备</span><span class="arrow right"></span></button><!----></section><!--]--></li><li><!--[--><section class="sidebar-group"><button class="sidebar-heading clickable"><i class="icon iconfont icon-java"></i><span class="title">Java</span><span class="arrow right"></span></button><!----></section><!--]--></li><li><!--[--><section class="sidebar-group"><button class="sidebar-heading clickable"><i class="icon iconfont icon-computer"></i><span class="title">计算机基础</span><span class="arrow right"></span></button><!----></section><!--]--></li><li><!--[--><section class="sidebar-group"><button class="sidebar-heading clickable"><i class="icon iconfont icon-database"></i><span class="title">数据库</span><span class="arrow right"></span></button><!----></section><!--]--></li><li><!--[--><section class="sidebar-group"><button class="sidebar-heading clickable"><i class="icon iconfont icon-Tools"></i><span class="title">开发工具</span><span class="arrow right"></span></button><!----></section><!--]--></li><li><!--[--><section class="sidebar-group"><button class="sidebar-heading clickable active"><i class="icon iconfont icon-xitongsheji"></i><span class="title">系统设计</span><span class="arrow down"></span></button><ul class="sidebar-links"><li><!--[--><a href="/system-design/system-design-questions.html" class="nav-link sidebar-link sidebar-page" arialabel="系统设计常见面试总结"><!---->系统设计常见面试总结<!----></a><ul class="sidebar-sub-headers"></ul><!--]--></li><li><!--[--><section class="sidebar-group"><button class="sidebar-heading clickable"><i class="icon iconfont icon-basic"></i><span class="title">基础</span><span class="arrow right"></span></button><!----></section><!--]--></li><li><!--[--><section class="sidebar-group"><button class="sidebar-heading clickable active"><i class="icon iconfont icon-framework"></i><span class="title">常用框架</span><span class="arrow down"></span></button><ul class="sidebar-links"><li><!--[--><section class="sidebar-group"><button class="sidebar-heading clickable"><!----><span class="title">Spring</span><span class="arrow right"></span></button><!----></section><!--]--></li><li><!--[--><a aria-current="page" href="/system-design/framework/mybatis/mybatis-interview.html" class="router-link-active router-link-exact-active nav-link active sidebar-link sidebar-page active" arialabel="MyBatis 常见面试总结"><!---->MyBatis 常见面试总结<!----></a><ul class="sidebar-sub-headers"></ul><!--]--></li><li><!--[--><a href="/system-design/framework/netty.html" class="nav-link sidebar-link sidebar-page" arialabel="Netty 知识点&amp;面试题总结"><!---->Netty 知识点&amp;面试题总结<!----></a><ul class="sidebar-sub-headers"></ul><!--]--></li><li><!--[--><section class="sidebar-group"><p class="sidebar-heading"><!----><span class="title">SpringCloud</span><!----></p><ul class="sidebar-links"><li><!--[--><a href="/system-design/framework/springcloud/springcloud-intro.html" class="nav-link sidebar-link sidebar-page" arialabel="Spring Cloud 入门"><!---->Spring Cloud 入门<!----></a><ul class="sidebar-sub-headers"></ul><!--]--></li></ul></section><!--]--></li></ul></section><!--]--></li><li><!--[--><section class="sidebar-group"><button class="sidebar-heading clickable"><i class="icon iconfont icon-security-fill"></i><span class="title">安全</span><span class="arrow right"></span></button><!----></section><!--]--></li><li><!--[--><a href="/system-design/schedule-task.html" class="nav-link sidebar-link sidebar-page" arialabel="Java定时任务大揭秘"><!---->Java定时任务大揭秘<!----></a><ul class="sidebar-sub-headers"></ul><!--]--></li></ul></section><!--]--></li><li><!--[--><section class="sidebar-group"><button class="sidebar-heading clickable"><i class="icon iconfont icon-distributed-network"></i><span class="title">分布式</span><span class="arrow right"></span></button><!----></section><!--]--></li><li><!--[--><section class="sidebar-group"><button class="sidebar-heading clickable"><i class="icon iconfont icon-et-performance"></i><span class="title">高性能</span><span class="arrow right"></span></button><!----></section><!--]--></li><li><!--[--><section class="sidebar-group"><button class="sidebar-heading clickable"><i class="icon iconfont icon-CalendarAvailability-1"></i><span class="title">高可用</span><span class="arrow right"></span></button><!----></section><!--]--></li></ul><!--[--><!----><!--]--></aside><!--[--><main class="page" id="main-content"><!----><nav class="breadcrumb disable"></nav><div class="page-title"><h1><!---->MyBatis 常见面试总结</h1><div class="article-info"><span class="author-info" arialabel="作者🖊" isoriginal="false" pageview="false" color="false"><svg xmlns="http://www.w3.org/2000/svg" class="icon author-icon" viewbox="0 0 1024 1024" arialabelledby="author"><title id="author" lang="en">author icon</title><g fill="currentColor"><path d="M649.6 633.6c86.4-48 147.2-144 147.2-249.6 0-160-128-288-288-288s-288 128-288 288c0 108.8 57.6 201.6 147.2 249.6-121.6 48-214.4 153.6-240 288-3.2 9.6 0 19.2 6.4 25.6 3.2 9.6 12.8 12.8 22.4 12.8h704c9.6 0 19.2-3.2 25.6-12.8 6.4-6.4 9.6-16 6.4-25.6-25.6-134.4-121.6-240-243.2-288z"></path></g></svg><span><a class="author-item" href="https://javaguide.cn/" target="_blank" rel="noopener noreferrer">Guide</a></span><span property="author" content="Guide"></span></span><!----><!----><span class="date-info" arialabel="写作日期📅" isoriginal="false" pageview="false" color="false"><svg xmlns="http://www.w3.org/2000/svg" class="icon calendar-icon" viewbox="0 0 1024 1024" arialabelledby="calendar"><title id="calendar" lang="en">calendar icon</title><g fill="currentColor"><path d="M716.4 110.137c0-18.753-14.72-33.473-33.472-33.473-18.753 0-33.473 14.72-33.473 33.473v33.473h66.993v-33.473zm-334.87 0c0-18.753-14.72-33.473-33.473-33.473s-33.52 14.72-33.52 33.473v33.473h66.993v-33.473zm468.81 33.52H716.4v100.465c0 18.753-14.72 33.473-33.472 33.473a33.145 33.145 0 01-33.473-33.473V143.657H381.53v100.465c0 18.753-14.72 33.473-33.473 33.473a33.145 33.145 0 01-33.473-33.473V143.657H180.6A134.314 134.314 0 0046.66 277.595v535.756A134.314 134.314 0 00180.6 947.289h669.74a134.36 134.36 0 00133.94-133.938V277.595a134.314 134.314 0 00-133.94-133.938zm33.473 267.877H147.126a33.145 33.145 0 01-33.473-33.473c0-18.752 14.72-33.473 33.473-33.473h736.687c18.752 0 33.472 14.72 33.472 33.473a33.145 33.145 0 01-33.472 33.473z"></path></g></svg><span>2020年2月12日</span><meta property="datePublished" content="2020-02-12T10:36:51.000Z"></span><!----><span class="words-info" arialabel="字数🔠" isoriginal="false" pageview="false" color="false"><svg xmlns="http://www.w3.org/2000/svg" class="icon word-icon" viewbox="0 0 1024 1024" arialabelledby="word"><title id="word" lang="en">word icon</title><g fill="currentColor"><path d="M518.217 432.64V73.143A73.143 73.143 0 01603.43 1.097a512 512 0 01419.474 419.474 73.143 73.143 0 01-72.046 85.212H591.36a73.143 73.143 0 01-73.143-73.143z"></path><path d="M493.714 566.857h340.297a73.143 73.143 0 0173.143 85.577A457.143 457.143 0 11371.566 117.76a73.143 73.143 0 0185.577 73.143v339.383a36.571 36.571 0 0036.571 36.571z"></path></g></svg><span>约 4224 字</span><meta property="wordCount" content="4224"></span></div><hr></div><div class="toc-place-holder"><aside id="toc-list"></aside></div><!----><div class="theme-hope-content"><!--[--><h1 id="mybatis-常见面试总结" tabindex="-1"><a class="header-anchor" href="#mybatis-常见面试总结" aria-hidden="true">#</a> MyBatis 常见面试总结</h1><blockquote><p>本篇文章是 JavaGuide 收集自网络，原出处不明。</p></blockquote><p>MyBatis 技术内幕系列博客，从原理和源码角度，介绍了其内部实现细节，无论是写的好与不好，我确实是用心写了，由于并不是介绍如何使用 MyBatis 的文章，所以，一些参数使用细节略掉了，我们的目标是介绍 MyBatis 的技术架构和重要组成部分，以及基本运行原理。</p><p>博客写的很辛苦，但是写出来却不一定好看，所谓开始很兴奋，过程很痛苦，结束很遗憾。要求不高，只要读者能从系列博客中，学习到一点其他博客所没有的技术点，作为作者，我就很欣慰了，我也读别人写的博客，通常对自己当前研究的技术，是很有帮助的。</p><p>尽管还有很多可写的内容，但是，我认为再写下去已经没有意义，任何其他小的功能点，都是在已经介绍的基本框架和基本原理下运行的，只有结束，才能有新的开始。写博客也积攒了一些经验，源码多了感觉就是复制黏贴，源码少了又觉得是空谈原理，将来再写博客，我希望是“精炼博文”，好读好懂美观读起来又不累，希望自己能再写一部开源分布式框架原理系列博客。</p><p>有胆就来，我出几道 MyBatis 面试题，看你能回答上来几道（都是我出的，可不是网上找的）。</p><h4 id="_1、-和-的区别是什么" tabindex="-1"><a class="header-anchor" href="#_1、-和-的区别是什么" aria-hidden="true">#</a> 1、#{}和${}的区别是什么？</h4><p>注：这道题是面试官面试我同事的。</p><p>答：</p><ul><li><code>${}</code>是 Properties 文件中的变量占位符，它可以用于标签属性值和 sql 内部，属于静态文本替换，比如${driver}会被静态替换为<code>com.mysql.jdbc. Driver</code>。</li><li><code>#{}</code>是 sql 的参数占位符，MyBatis 会将 sql 中的<code>#{}</code>替换为? 号，在 sql 执行前会使用 PreparedStatement 的参数设置方法，按序给 sql 的? 号占位符设置参数值，比如 ps.setInt(0, parameterValue)，<code>#{item.name}</code> 的取值方式为使用反射从参数对象中获取 item 对象的 name 属性值，相当于 <code>param.getItem().getName()</code>。</li></ul><h4 id="_2、xml-映射文件中-除了常见的-select-insert-update-delete-标签之外-还有哪些标签" tabindex="-1"><a class="header-anchor" href="#_2、xml-映射文件中-除了常见的-select-insert-update-delete-标签之外-还有哪些标签" aria-hidden="true">#</a> 2、Xml 映射文件中，除了常见的 select|insert|update|delete 标签之外，还有哪些标签？</h4><p>注：这道题是京东面试官面试我时问的。</p><p>答：还有很多其他的标签， <code>&lt;resultMap&gt;</code> 、 <code>&lt;parameterMap&gt;</code> 、 <code>&lt;sql&gt;</code> 、 <code>&lt;include&gt;</code> 、 <code>&lt;selectKey&gt;</code> ，加上动态 sql 的 9 个标签， <code>trim|where|set|foreach|if|choose|when|otherwise|bind</code> 等，其中 <code>&lt;sql&gt;</code> 为 sql 片段标签，通过 <code>&lt;include&gt;</code> 标签引入 sql 片段， <code>&lt;selectKey&gt;</code> 为不支持自增的主键生成策略标签。</p><h4 id="_3、最佳实践中-通常一个-xml-映射文件-都会写一个-dao-接口与之对应-请问-这个-dao-接口的工作原理是什么-dao-接口里的方法-参数不同时-方法能重载吗" tabindex="-1"><a class="header-anchor" href="#_3、最佳实践中-通常一个-xml-映射文件-都会写一个-dao-接口与之对应-请问-这个-dao-接口的工作原理是什么-dao-接口里的方法-参数不同时-方法能重载吗" aria-hidden="true">#</a> 3、最佳实践中，通常一个 Xml 映射文件，都会写一个 Dao 接口与之对应，请问，这个 Dao 接口的工作原理是什么？Dao 接口里的方法，参数不同时，方法能重载吗？</h4><p>注：这道题也是京东面试官面试我被问的。</p><p>答：Dao 接口，就是人们常说的 <code>Mapper</code> 接口，接口的全限名，就是映射文件中的 namespace 的值，接口的方法名，就是映射文件中 <code>MappedStatement</code> 的 id 值，接口方法内的参数，就是传递给 sql 的参数。 <code>Mapper</code> 接口是没有实现类的，当调用接口方法时，接口全限名+方法名拼接字符串作为 key 值，可唯一定位一个 <code>MappedStatement</code> ，举例： <code>com.mybatis3.mappers. StudentDao.findStudentById</code> ，可以唯一找到 namespace 为 <code>com.mybatis3.mappers. StudentDao</code> 下面 <code>id = findStudentById</code> 的 <code>MappedStatement</code> 。在 MyBatis 中，每一个 <code>&lt;select&gt;</code> 、 <code>&lt;insert&gt;</code> 、 <code>&lt;update&gt;</code> 、 <code>&lt;delete&gt;</code> 标签，都会被解析为一个 <code>MappedStatement</code> 对象。</p><p><s>Dao 接口里的方法，是不能重载的，因为是全限名+方法名的保存和寻找策略。</s></p><p>Dao 接口里的方法可以重载，但是 Mybatis 的 XML 里面的 ID 不允许重复。</p><p>Mybatis 版本 3.3.0，亲测如下：</p><div class="language-java ext-java line-numbers-mode"><pre class="language-java"><code><span class="token doc-comment comment">/**
 * Mapper接口里面方法重载
 */</span>
<span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">StuMapper</span> <span class="token punctuation">{</span>

	<span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Student</span><span class="token punctuation">&gt;</span></span> <span class="token function">getAllStu</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

	<span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Student</span><span class="token punctuation">&gt;</span></span> <span class="token function">getAllStu</span><span class="token punctuation">(</span><span class="token annotation punctuation">@Param</span><span class="token punctuation">(</span><span class="token string">&quot;id&quot;</span><span class="token punctuation">)</span> <span class="token class-name">Integer</span> id<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>然后在 <code>StuMapper.xml</code> 中利用 Mybatis 的动态 sql 就可以实现。</p><div class="language-java ext-java line-numbers-mode"><pre class="language-java"><code>	<span class="token operator">&lt;</span>select id<span class="token operator">=</span><span class="token string">&quot;getAllStu&quot;</span> resultType<span class="token operator">=</span><span class="token string">&quot;com.pojo.Student&quot;</span><span class="token operator">&gt;</span>
 		select <span class="token operator">*</span> from student
		<span class="token generics"><span class="token punctuation">&lt;</span>where<span class="token punctuation">&gt;</span></span>
			<span class="token operator">&lt;</span><span class="token keyword">if</span> test<span class="token operator">=</span><span class="token string">&quot;id != null&quot;</span><span class="token operator">&gt;</span>
				id <span class="token operator">=</span> #<span class="token punctuation">{</span>id<span class="token punctuation">}</span>
			<span class="token operator">&lt;</span><span class="token operator">/</span><span class="token keyword">if</span><span class="token operator">&gt;</span>
		<span class="token operator">&lt;</span><span class="token operator">/</span>where<span class="token operator">&gt;</span>
 	<span class="token operator">&lt;</span><span class="token operator">/</span>select<span class="token operator">&gt;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>能正常运行，并能得到相应的结果，这样就实现了在 Dao 接口中写重载方法。</p><p><strong>Mybatis 的 Dao 接口可以有多个重载方法，但是多个接口对应的映射必须只有一个，否则启动会报错。</strong></p><p>相关 issue ：<a href="https://github.com/Snailclimb/JavaGuide/issues/1122" target="_blank" rel="noopener noreferrer">更正：Dao 接口里的方法可以重载，但是 Mybatis 的 XML 里面的 ID 不允许重复！<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a>。</p><p>Dao 接口的工作原理是 JDK 动态代理，MyBatis 运行时会使用 JDK 动态代理为 Dao 接口生成代理 proxy 对象，代理对象 proxy 会拦截接口方法，转而执行 <code>MappedStatement</code> 所代表的 sql，然后将 sql 执行结果返回。</p><h5 id="补充" tabindex="-1"><a class="header-anchor" href="#补充" aria-hidden="true">#</a> <mark>补充：</mark></h5><p>Dao 接口方法可以重载，但是需要满足以下条件：</p><ol><li>仅有一个无参方法和一个有参方法</li><li>多个有参方法时，参数数量必须一致。且使用相同的 <code>@Param</code> ，或者使用 <code>param1</code> 这种</li></ol><p>测试如下：</p><p><code>PersonDao.java</code></p><div class="language-java ext-java line-numbers-mode"><pre class="language-java"><code><span class="token class-name">Person</span> <span class="token function">queryById</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token class-name">Person</span> <span class="token function">queryById</span><span class="token punctuation">(</span><span class="token annotation punctuation">@Param</span><span class="token punctuation">(</span><span class="token string">&quot;id&quot;</span><span class="token punctuation">)</span> <span class="token class-name">Long</span> id<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token class-name">Person</span> <span class="token function">queryById</span><span class="token punctuation">(</span><span class="token annotation punctuation">@Param</span><span class="token punctuation">(</span><span class="token string">&quot;id&quot;</span><span class="token punctuation">)</span> <span class="token class-name">Long</span> id<span class="token punctuation">,</span> <span class="token annotation punctuation">@Param</span><span class="token punctuation">(</span><span class="token string">&quot;name&quot;</span><span class="token punctuation">)</span> <span class="token class-name">String</span> name<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p><code>PersonMapper.xml</code></p><div class="language-xml ext-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>select</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>queryById<span class="token punctuation">&quot;</span></span> <span class="token attr-name">resultMap</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>PersonMap<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    select
      id, name, age, address
    from person
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>where</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>if</span> <span class="token attr-name">test</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>id != null<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
            id = #{id}
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>if</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>if</span> <span class="token attr-name">test</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>name != null and name != <span class="token punctuation">&#39;</span><span class="token punctuation">&#39;</span><span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
            name = #{name}
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>if</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>where</span><span class="token punctuation">&gt;</span></span>
    limit 1
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>select</span><span class="token punctuation">&gt;</span></span>
</code></pre><div class="line-numbers" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><p><code>org.apache.ibatis.scripting.xmltags. DynamicContext. ContextAccessor#getProperty</code> 方法用于获取 <code>&lt;if&gt;</code> 标签中的条件值</p><div class="language-java ext-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token class-name">Object</span> <span class="token function">getProperty</span><span class="token punctuation">(</span><span class="token class-name">Map</span> context<span class="token punctuation">,</span> <span class="token class-name">Object</span> target<span class="token punctuation">,</span> <span class="token class-name">Object</span> name<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token class-name">Map</span> map <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">Map</span><span class="token punctuation">)</span> target<span class="token punctuation">;</span>

  <span class="token class-name">Object</span> result <span class="token operator">=</span> map<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>map<span class="token punctuation">.</span><span class="token function">containsKey</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span> <span class="token operator">||</span> result <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> result<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>

  <span class="token class-name">Object</span> parameterObject <span class="token operator">=</span> map<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>PARAMETER_OBJECT_KEY<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>parameterObject <span class="token keyword">instanceof</span> <span class="token class-name">Map</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">Map</span><span class="token punctuation">)</span>parameterObject<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>

  <span class="token keyword">return</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><p><code>parameterObject</code> 为 map，存放的是 Dao 接口中参数相关信息。</p><p><code>((Map)parameterObject).get(name)</code> 方法如下</p><div class="language-java ext-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token class-name">V</span> <span class="token function">get</span><span class="token punctuation">(</span><span class="token class-name">Object</span> key<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">containsKey</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">BindingException</span><span class="token punctuation">(</span><span class="token string">&quot;Parameter &#39;&quot;</span> <span class="token operator">+</span> key <span class="token operator">+</span> <span class="token string">&quot;&#39; not found. Available parameters are &quot;</span> <span class="token operator">+</span> <span class="token function">keySet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><ol><li><code>queryById()</code>方法执行时，<code>parameterObject</code>为 null，<code>getProperty</code>方法返回 null 值，<code>&lt;if&gt;</code>标签获取的所有条件值都为 null，所有条件不成立，动态 sql 可以正常执行。</li><li><code>queryById(1L)</code>方法执行时，<code>parameterObject</code>为 map，包含了<code>id</code>和<code>param1</code>两个 key 值。当获取<code>&lt;if&gt;</code>标签中<code>name</code>的属性值时，进入<code>((Map)parameterObject).get(name)</code>方法中，map 中 key 不包含<code>name</code>，所以抛出异常。</li><li><code>queryById(1L,&quot;1&quot;)</code>方法执行时，<code>parameterObject</code>中包含<code>id</code>,<code>param1</code>,<code>name</code>,<code>param2</code>四个 key 值，<code>id</code>和<code>name</code>属性都可以获取到，动态 sql 正常执行。</li></ol><h4 id="_4、mybatis-是如何进行分页的-分页插件的原理是什么" tabindex="-1"><a class="header-anchor" href="#_4、mybatis-是如何进行分页的-分页插件的原理是什么" aria-hidden="true">#</a> 4、MyBatis 是如何进行分页的？分页插件的原理是什么？</h4><p>注：我出的。</p><p>答：<strong>(1)</strong> MyBatis 使用 RowBounds 对象进行分页，它是针对 ResultSet 结果集执行的内存分页，而非物理分页；<strong>(2)</strong> 可以在 sql 内直接书写带有物理分页的参数来完成物理分页功能，<strong>(3)</strong> 也可以使用分页插件来完成物理分页。</p><p>分页插件的基本原理是使用 MyBatis 提供的插件接口，实现自定义插件，在插件的拦截方法内拦截待执行的 sql，然后重写 sql，根据 dialect 方言，添加对应的物理分页语句和物理分页参数。</p><p>举例： <code>select _ from student</code> ，拦截 sql 后重写为： <code>select t._ from （select \* from student）t limit 0，10</code></p><h4 id="_5、简述-mybatis-的插件运行原理-以及如何编写一个插件。" tabindex="-1"><a class="header-anchor" href="#_5、简述-mybatis-的插件运行原理-以及如何编写一个插件。" aria-hidden="true">#</a> 5、简述 MyBatis 的插件运行原理，以及如何编写一个插件。</h4><p>注：我出的。</p><p>答：MyBatis 仅可以编写针对 <code>ParameterHandler</code> 、 <code>ResultSetHandler</code> 、 <code>StatementHandler</code> 、 <code>Executor</code> 这 4 种接口的插件，MyBatis 使用 JDK 的动态代理，为需要拦截的接口生成代理对象以实现接口方法拦截功能，每当执行这 4 种接口对象的方法时，就会进入拦截方法，具体就是 <code>InvocationHandler</code> 的 <code>invoke()</code> 方法，当然，只会拦截那些你指定需要拦截的方法。</p><p>实现 MyBatis 的 Interceptor 接口并复写 <code>intercept()</code> 方法，然后在给插件编写注解，指定要拦截哪一个接口的哪些方法即可，记住，别忘了在配置文件中配置你编写的插件。</p><h4 id="_6、mybatis-执行批量插入-能返回数据库主键列表吗" tabindex="-1"><a class="header-anchor" href="#_6、mybatis-执行批量插入-能返回数据库主键列表吗" aria-hidden="true">#</a> 6、MyBatis 执行批量插入，能返回数据库主键列表吗？</h4><p>注：我出的。</p><p>答：能，JDBC 都能，MyBatis 当然也能。</p><h4 id="_7、mybatis-动态-sql-是做什么的-都有哪些动态-sql-能简述一下动态-sql-的执行原理不" tabindex="-1"><a class="header-anchor" href="#_7、mybatis-动态-sql-是做什么的-都有哪些动态-sql-能简述一下动态-sql-的执行原理不" aria-hidden="true">#</a> 7、MyBatis 动态 sql 是做什么的？都有哪些动态 sql？能简述一下动态 sql 的执行原理不？</h4><p>注：我出的。</p><p>答：MyBatis 动态 sql 可以让我们在 Xml 映射文件内，以标签的形式编写动态 sql，完成逻辑判断和动态拼接 sql 的功能，MyBatis 提供了 9 种动态 sql 标签 <code>trim|where|set|foreach|if|choose|when|otherwise|bind</code> 。</p><p>其执行原理为，使用 OGNL 从 sql 参数对象中计算表达式的值，根据表达式的值动态拼接 sql，以此来完成动态 sql 的功能。</p><h4 id="_8、mybatis-是如何将-sql-执行结果封装为目标对象并返回的-都有哪些映射形式" tabindex="-1"><a class="header-anchor" href="#_8、mybatis-是如何将-sql-执行结果封装为目标对象并返回的-都有哪些映射形式" aria-hidden="true">#</a> 8、MyBatis 是如何将 sql 执行结果封装为目标对象并返回的？都有哪些映射形式？</h4><p>注：我出的。</p><p>答：第一种是使用 <code>&lt;resultMap&gt;</code> 标签，逐一定义列名和对象属性名之间的映射关系。第二种是使用 sql 列的别名功能，将列别名书写为对象属性名，比如 T_NAME AS NAME，对象属性名一般是 name，小写，但是列名不区分大小写，MyBatis 会忽略列名大小写，智能找到与之对应对象属性名，你甚至可以写成 T_NAME AS NaMe，MyBatis 一样可以正常工作。</p><p>有了列名与属性名的映射关系后，MyBatis 通过反射创建对象，同时使用反射给对象的属性逐一赋值并返回，那些找不到映射关系的属性，是无法完成赋值的。</p><h4 id="_9、mybatis-能执行一对一、一对多的关联查询吗-都有哪些实现方式-以及它们之间的区别。" tabindex="-1"><a class="header-anchor" href="#_9、mybatis-能执行一对一、一对多的关联查询吗-都有哪些实现方式-以及它们之间的区别。" aria-hidden="true">#</a> 9、MyBatis 能执行一对一、一对多的关联查询吗？都有哪些实现方式，以及它们之间的区别。</h4><p>注：我出的。</p><p>关联对象查询，有两种实现方式，一种是单独发送一个 sql 去查询关联对象，赋给主对象，然后返回主对象。另一种是使用嵌套查询，嵌套查询的含义为使用 join 查询，一部分列是 A 对象的属性值，另外一部分列是关联对象 B 的属性值，好处是只发一个 sql 查询，就可以把主对象和其关联对象查出来。</p><p>那么问题来了，join 查询出来 100 条记录，如何确定主对象是 5 个，而不是 100 个？其去重复的原理是 <code>&lt;resultMap&gt;</code> 标签内的 <code>&lt;id&gt;</code> 子标签，指定了唯一确定一条记录的 id 列，MyBatis 根据 <code>&lt;id&gt;</code> 列值来完成 100 条记录的去重复功能， <code>&lt;id&gt;</code> 可以有多个，代表了联合主键的语意。</p><p>同样主对象的关联对象，也是根据这个原理去重复的，尽管一般情况下，只有主对象会有重复记录，关联对象一般不会重复。</p><p>举例：下面 join 查询出来 6 条记录，一、二列是 Teacher 对象列，第三列为 Student 对象列，MyBatis 去重复处理后，结果为 1 个老师 6 个学生，而不是 6 个老师 6 个学生。</p><table><thead><tr><th>t_id</th><th>t_name</th><th>s_id</th></tr></thead><tbody><tr><td>1</td><td>teacher</td><td>38</td></tr><tr><td>1</td><td>teacher</td><td>39</td></tr><tr><td>1</td><td>teacher</td><td>40</td></tr><tr><td>1</td><td>teacher</td><td>41</td></tr><tr><td>1</td><td>teacher</td><td>42</td></tr><tr><td>1</td><td>teacher</td><td>43</td></tr></tbody></table><h4 id="_10、mybatis-是否支持延迟加载-如果支持-它的实现原理是什么" tabindex="-1"><a class="header-anchor" href="#_10、mybatis-是否支持延迟加载-如果支持-它的实现原理是什么" aria-hidden="true">#</a> 10、MyBatis 是否支持延迟加载？如果支持，它的实现原理是什么？</h4><p>注：我出的。</p><p>答：MyBatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载，association 指的就是一对一，collection 指的就是一对多查询。在 MyBatis 配置文件中，可以配置是否启用延迟加载 <code>lazyLoadingEnabled=true|false。</code></p><p>它的原理是，使用 <code>CGLIB</code> 创建目标对象的代理对象，当调用目标方法时，进入拦截器方法，比如调用 <code>a.getB().getName()</code> ，拦截器 <code>invoke()</code> 方法发现 <code>a.getB()</code> 是 null 值，那么就会单独发送事先保存好的查询关联 B 对象的 sql，把 B 查询上来，然后调用 a.setB(b)，于是 a 的对象 b 属性就有值了，接着完成 <code>a.getB().getName()</code> 方法的调用。这就是延迟加载的基本原理。</p><p>当然了，不光是 MyBatis，几乎所有的包括 Hibernate，支持延迟加载的原理都是一样的。</p><h4 id="_11、mybatis-的-xml-映射文件中-不同的-xml-映射文件-id-是否可以重复" tabindex="-1"><a class="header-anchor" href="#_11、mybatis-的-xml-映射文件中-不同的-xml-映射文件-id-是否可以重复" aria-hidden="true">#</a> 11、MyBatis 的 Xml 映射文件中，不同的 Xml 映射文件，id 是否可以重复？</h4><p>注：我出的。</p><p>答：不同的 Xml 映射文件，如果配置了 namespace，那么 id 可以重复；如果没有配置 namespace，那么 id 不能重复；毕竟 namespace 不是必须的，只是最佳实践而已。</p><p>原因就是 namespace+id 是作为 <code>Map&lt;String, MappedStatement&gt;</code> 的 key 使用的，如果没有 namespace，就剩下 id，那么，id 重复会导致数据互相覆盖。有了 namespace，自然 id 就可以重复，namespace 不同，namespace+id 自然也就不同。</p><h4 id="_12、mybatis-中如何执行批处理" tabindex="-1"><a class="header-anchor" href="#_12、mybatis-中如何执行批处理" aria-hidden="true">#</a> 12、MyBatis 中如何执行批处理？</h4><p>注：我出的。</p><p>答：使用 BatchExecutor 完成批处理。</p><h4 id="_13、mybatis-都有哪些-executor-执行器-它们之间的区别是什么" tabindex="-1"><a class="header-anchor" href="#_13、mybatis-都有哪些-executor-执行器-它们之间的区别是什么" aria-hidden="true">#</a> 13、MyBatis 都有哪些 Executor 执行器？它们之间的区别是什么？</h4><p>注：我出的</p><p>答：MyBatis 有三种基本的 Executor 执行器，** <code>SimpleExecutor</code> 、 <code>ReuseExecutor</code> 、 <code>BatchExecutor</code> 。**</p><p>** <code>SimpleExecutor</code> ：**每执行一次 update 或 select，就开启一个 Statement 对象，用完立刻关闭 Statement 对象。</p><p>** <code>ReuseExecutor</code> ：**执行 update 或 select，以 sql 作为 key 查找 Statement 对象，存在就使用，不存在就创建，用完后，不关闭 Statement 对象，而是放置于 Map&lt;String, Statement&gt;内，供下一次使用。简言之，就是重复使用 Statement 对象。</p><p>** <code>BatchExecutor</code> ：**执行 update（没有 select，JDBC 批处理不支持 select），将所有 sql 都添加到批处理中（addBatch()），等待统一执行（executeBatch()），它缓存了多个 Statement 对象，每个 Statement 对象都是 addBatch()完毕后，等待逐一执行 executeBatch()批处理。与 JDBC 批处理相同。</p><p>作用范围：Executor 的这些特点，都严格限制在 SqlSession 生命周期范围内。</p><h4 id="_14、mybatis-中如何指定使用哪一种-executor-执行器" tabindex="-1"><a class="header-anchor" href="#_14、mybatis-中如何指定使用哪一种-executor-执行器" aria-hidden="true">#</a> 14、MyBatis 中如何指定使用哪一种 Executor 执行器？</h4><p>注：我出的</p><p>答：在 MyBatis 配置文件中，可以指定默认的 ExecutorType 执行器类型，也可以手动给 <code>DefaultSqlSessionFactory</code> 的创建 SqlSession 的方法传递 ExecutorType 类型参数。</p><h4 id="_15、mybatis-是否可以映射-enum-枚举类" tabindex="-1"><a class="header-anchor" href="#_15、mybatis-是否可以映射-enum-枚举类" aria-hidden="true">#</a> 15、MyBatis 是否可以映射 Enum 枚举类？</h4><p>注：我出的</p><p>答：MyBatis 可以映射枚举类，不单可以映射枚举类，MyBatis 可以映射任何对象到表的一列上。映射方式为自定义一个 <code>TypeHandler</code> ，实现 <code>TypeHandler</code> 的 <code>setParameter()</code> 和 <code>getResult()</code> 接口方法。 <code>TypeHandler</code> 有两个作用，一是完成从 javaType 至 jdbcType 的转换，二是完成 jdbcType 至 javaType 的转换，体现为 <code>setParameter()</code> 和 <code>getResult()</code> 两个方法，分别代表设置 sql 问号占位符参数和获取列查询结果。</p><h4 id="_16、mybatis-映射文件中-如果-a-标签通过-include-引用了-b-标签的内容-请问-b-标签能否定义在-a-标签的后面-还是说必须定义在-a-标签的前面" tabindex="-1"><a class="header-anchor" href="#_16、mybatis-映射文件中-如果-a-标签通过-include-引用了-b-标签的内容-请问-b-标签能否定义在-a-标签的后面-还是说必须定义在-a-标签的前面" aria-hidden="true">#</a> 16、MyBatis 映射文件中，如果 A 标签通过 include 引用了 B 标签的内容，请问，B 标签能否定义在 A 标签的后面，还是说必须定义在 A 标签的前面？</h4><p>注：我出的</p><p>答：虽然 MyBatis 解析 Xml 映射文件是按照顺序解析的，但是，被引用的 B 标签依然可以定义在任何地方，MyBatis 都可以正确识别。</p><p>原理是，MyBatis 解析 A 标签，发现 A 标签引用了 B 标签，但是 B 标签尚未解析到，尚不存在，此时，MyBatis 会将 A 标签标记为未解析状态，然后继续解析余下的标签，包含 B 标签，待所有标签解析完毕，MyBatis 会重新解析那些被标记为未解析的标签，此时再解析 A 标签时，B 标签已经存在，A 标签也就可以正常解析完成了。</p><h4 id="_17、简述-mybatis-的-xml-映射文件和-mybatis-内部数据结构之间的映射关系" tabindex="-1"><a class="header-anchor" href="#_17、简述-mybatis-的-xml-映射文件和-mybatis-内部数据结构之间的映射关系" aria-hidden="true">#</a> 17、简述 MyBatis 的 Xml 映射文件和 MyBatis 内部数据结构之间的映射关系？</h4><p>注：我出的</p><p>答：MyBatis 将所有 Xml 配置信息都封装到 All-In-One 重量级对象 Configuration 内部。在 Xml 映射文件中， <code>&lt;parameterMap&gt;</code> 标签会被解析为 <code>ParameterMap</code> 对象，其每个子元素会被解析为 ParameterMapping 对象。 <code>&lt;resultMap&gt;</code> 标签会被解析为 <code>ResultMap</code> 对象，其每个子元素会被解析为 <code>ResultMapping</code> 对象。每一个 <code>&lt;select&gt;、&lt;insert&gt;、&lt;update&gt;、&lt;delete&gt;</code> 标签均会被解析为 <code>MappedStatement</code> 对象，标签内的 sql 会被解析为 BoundSql 对象。</p><h4 id="_18、为什么说-mybatis-是半自动-orm-映射工具-它与全自动的区别在哪里" tabindex="-1"><a class="header-anchor" href="#_18、为什么说-mybatis-是半自动-orm-映射工具-它与全自动的区别在哪里" aria-hidden="true">#</a> 18、为什么说 MyBatis 是半自动 ORM 映射工具？它与全自动的区别在哪里？</h4><p>注：我出的</p><p>答：Hibernate 属于全自动 ORM 映射工具，使用 Hibernate 查询关联对象或者关联集合对象时，可以根据对象关系模型直接获取，所以它是全自动的。而 MyBatis 在查询关联对象或关联集合对象时，需要手动编写 sql 来完成，所以，称之为半自动 ORM 映射工具。</p><p>面试题看似都很简单，但是想要能正确回答上来，必定是研究过源码且深入的人，而不是仅会使用的人或者用的很熟的人，以上所有面试题及其答案所涉及的内容，在我的 MyBatis 系列博客中都有详细讲解和原理分析。</p><!--]--></div><!----><footer class="page-meta"><div class="meta-item edit-link"><a href="https://github.com/Snailclimb/JavaGuide/edit/main/docs/system-design/framework/mybatis/mybatis-interview.md" rel="noopener noreferrer" target="_blank" arialabel="编辑此页" class="nav-link label"><!--[--><svg xmlns="http://www.w3.org/2000/svg" class="icon edit-icon" viewbox="0 0 1024 1024" arialabelledby="edit"><title id="edit" lang="en">edit icon</title><g fill="currentColor"><path d="M430.818 653.65a60.46 60.46 0 0 1-50.96-93.281l71.69-114.012 7.773-10.365L816.038 80.138A60.46 60.46 0 0 1 859.225 62a60.46 60.46 0 0 1 43.186 18.138l43.186 43.186a60.46 60.46 0 0 1 0 86.373L588.879 565.55l-8.637 8.637-117.466 68.234a60.46 60.46 0 0 1-31.958 11.229z"></path><path d="M728.802 962H252.891A190.883 190.883 0 0 1 62.008 771.98V296.934a190.883 190.883 0 0 1 190.883-192.61h267.754a60.46 60.46 0 0 1 0 120.92H252.891a69.962 69.962 0 0 0-69.098 69.099V771.98a69.962 69.962 0 0 0 69.098 69.098h475.911A69.962 69.962 0 0 0 797.9 771.98V503.363a60.46 60.46 0 1 1 120.922 0V771.98A190.883 190.883 0 0 1 728.802 962z"></path></g></svg><!--]-->编辑此页<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!----></a></div><div class="meta-item update-time"><span class="label">上次编辑于: </span><span class="info">2021/11/9 18:47:58</span></div><div class="meta-item contributors"><span class="label">贡献者: </span><!--[--><!--[--><span class="contributor" title="email: koushuangbwcx@163.com">guide</span>,<!--]--><!--[--><span class="contributor" title="email: koushuangbwcx@163.com">shuang.kou</span>,<!--]--><!--[--><span class="contributor" title="email: lovechen1996428@qq.com">yamonc</span>,<!--]--><!--[--><span class="contributor" title="email: zhangkai33094@hundsun.com">zhangkai</span>,<!--]--><!--[--><span class="contributor" title="email: juzi214032@qq.com">桔子</span>,<!--]--><!--[--><span class="contributor" title="email: 48374300+wulnm@users.noreply.github.com">齐</span><!--]--><!--]--></div></footer><nav class="page-nav"><!----><a href="/system-design/framework/netty.html" class="nav-link next" arialabel="Netty 知识点&amp;面试题总结"><div class="hint">下一页<span class="arrow right"></span></div><div class="link">Netty 知识点&amp;面试题总结<!----></div></a></nav><!----><!----></main><!--]--><footer class="footer-wrapper"><div class="footer"><a href="https://beian.miit.gov.cn/" target="_blank">鄂ICP备2020015769号-1</a></div><div class="copyright">Copyright © 2022 Guide</div></footer></div><!--]--><!----><!--]--></div>
    <script type="module" src="/assets/app.93341f6d.js" defer></script>
  </body>
</html>
